#ifndef SERVER_HPP
#define SERVER_HPP

/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


class ServerBase
{
public:
    bool go;

    ServerBase()
    {

    }

    void error(const char *msg)
    {
        perror(msg);
        exit(1);
    }

    virtual void task(char buffer[256])
    {
        if(strncmp(buffer,"END",3)==0)
         {
            go=false;
            sleep(1);
        }
    }

    void start(uint16_t portno=7654)
    {
        int sockfd, newsockfd;
        socklen_t clilen;
        char buffer[256];
        struct sockaddr_in serv_addr, cli_addr;
        int n;

        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
            error("ERROR opening socket");
        bzero((char *) &serv_addr, sizeof(serv_addr));

        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(portno);

        const int       optVal = 1;
        const socklen_t optLen = sizeof(optVal);

        if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen)!=0)
        {
            error("ERROR on setsockopt");
        }


        if (bind(sockfd, (struct sockaddr *) &serv_addr,
                 sizeof(serv_addr)) < 0)
            error("ERROR on binding");
        listen(sockfd,5);
        clilen = sizeof(cli_addr);

        go=true;

        while (go)
        {

            newsockfd = accept(sockfd,
                               (struct sockaddr *) &cli_addr,
                               &clilen);
            if (newsockfd < 0)
                error("ERROR on accept");
            bzero(buffer,256);


            n = read(newsockfd,buffer,255);
            if (n < 0) {
                error("ERROR reading from socket");
                break;
            }

            printf("Here is the message: %s\n",buffer);

            task(buffer);


            n = write(newsockfd,"I got your message\n",19);

            if (n < 0) {
                error("ERROR writing to socket");
                break;
            }

            close(newsockfd);
        }
        close(sockfd);
    }

};







#endif // SERVER_HPP

